#region File Header
//-----------------------------------------------------------------------------
// SibLib
//
// Copyright (C) 2010 Julien Villers
// This program is distributed under the terms of the 
// GNU Lesser General Public License (LGPL).
// See Docs/lgpl.txt and Docs/gpl.txt
//-----------------------------------------------------------------------------
#endregion

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

namespace SibLib.GameState
{
    /// <summary>
    /// This kind of menu entry is used to toggle an option.
    /// </summary>
    public class MenuEntryToggle : MenuEntry
    {
        #region Protected Members
        /// <summary>
        /// Current value.
        /// </summary>
        protected bool m_Value;

        /// <summary>
        /// Text shown when entry value is 'true'.
        /// </summary>
        protected string m_TextEnabled;

        /// <summary>
        /// Text shown when entry value is 'false'.
        /// </summary>
        protected string m_TextDisabled;
        #endregion

        /// <summary>
        /// Value of toggle.
        /// </summary>
        /// <remarks>
        /// Direct setting of this doesn't trigger the ValueChanged event.
        /// </remarks>
        public bool Value
        {
            get { return m_Value; }
            set { m_Value = value; }
        }

        #region Events
        /// <summary>
        /// This event is fired when the player changes the value of this menu entry.
        /// </summary>
        public event EventHandler<PlayerIndexEventArgs> ValueChanged;

        /// <summary>
        /// Method for raising the ValueChanged event.
        /// </summary>
        protected internal virtual void OnValueChanged(PlayerIndex playerIndex)
        {
            if (ValueChanged != null)
                ValueChanged(this, new PlayerIndexEventArgs(playerIndex));
        }
        #endregion

        #region Initialization

        /// <summary>
        /// Full setup constructor.
        /// </summary>
        /// <param name="text">Entry name (should include ':' or ' ', etc...)</param>
        /// <param name="enabledText">Text displayed when value is true</param>
        /// <param name="disabledText">Text displayed when value is false</param>
        public MenuEntryToggle(string text, string enabledText, string disabledText) :
            base(text)
        {
            m_TextEnabled = enabledText;
            m_TextDisabled = disabledText;
            m_Value = false;
        }

        /// <summary>
        /// Constructor with default values of 'On' and 'Off'.
        /// </summary>
        /// <param name="text"></param>
        public MenuEntryToggle(string text) :
            this(text, "On", "Off")
        {
        }

        #endregion

        #region Update

        /// <summary>
        /// Toggle value.
        /// </summary>
        /// <param name="playerIndex"></param>
        protected internal override void OnSelectEntry(PlayerIndex playerIndex)
        {
            base.OnSelectEntry(playerIndex);

            ChangeValue(!m_Value, playerIndex);
        }

        /// <summary>
        /// Handle non-standard button input, including Left/Right, X, Plus/Minus.
        /// A is taken care of by OnSelectEntry().
        /// </summary>
        /// <param name="inputState">Current input state.</param>
        /// <param name="playerIndex">Controlling player index, only one checked.</param>
        protected internal override void OnCustomInput(InputState inputState, PlayerIndex playerIndex)
        {
            if (inputState.IsNewButtonPress(Buttons.LeftThumbstickLeft, playerIndex) ||
                inputState.IsNewButtonPress(Buttons.DPadLeft, playerIndex) ||
                //inputState.IsNewButtonPress(Buttons.X, playerIndex) ||
                inputState.IsNewKeyPress(Keys.Left, playerIndex) ||
                inputState.IsNewKeyPress(Keys.Subtract, playerIndex))
                ChangeValue(false, playerIndex);

            if (inputState.IsNewButtonPress(Buttons.LeftThumbstickRight, playerIndex) ||
                inputState.IsNewButtonPress(Buttons.DPadRight, playerIndex) ||
                //inputState.IsNewButtonPress(Buttons.A, playerIndex) ||
                inputState.IsNewKeyPress(Keys.Right, playerIndex) ||
                inputState.IsNewKeyPress(Keys.Add, playerIndex))
                ChangeValue(true, playerIndex);

            base.OnCustomInput(inputState, playerIndex);
        }

        protected void ChangeValue(bool newValue, PlayerIndex playerIndex)
        {
            if (m_Value != newValue)
            {
                m_Value = newValue;
                OnValueChanged(playerIndex);
            }
        }

        #endregion

        #region Render

        protected override void Draw(SpriteBatch spriteBatch, SpriteFont font, Vector2 position, Color color, float scale)
        {
            Vector2 origin = new Vector2(0, font.LineSpacing / 2);
            spriteBatch.DrawString(font, m_Text + ((m_Value) ? m_TextEnabled : m_TextDisabled), position, color, 0, origin, scale, SpriteEffects.None, 0);
        }

        #endregion
    }
}